#include <iostream>
#include <pthread.h>

#include <log4cxx/logger.h>
#include <log4cxx/xml/domconfigurator.h>

#include "CnfSvrClient.h"

#define THREAD_NUM 100

using std::cout;
using std::endl;
using std::ostringstream;

int g_counter;
pthread_mutex_t g_mutex;
time_t g_time_start;

string g_log_conf_file;

int parse_args(int argc, char * argv[]) {
        char c;
        while(-1 != (c = getopt(argc, argv, "l:"))) {
                switch(c) {
                        case 'l':
                                g_log_conf_file = optarg;
                                break;

                        default:
                                break;
                }
        }
        return 1;
}

int add_counter() {
	pthread_mutex_lock(&g_mutex);
	g_counter++;
	pthread_mutex_unlock(&g_mutex);
	time_t time_now = time(NULL);
	if (g_counter % 100 == 0 && (time_now - g_time_start) > 1) {
		cout << "rate:" << (g_counter / (time_now - g_time_start)) << endl;
	}
	return 0;
}

string ns_cnf_2_string(NS_CNF c) {
	ostringstream oss;
	oss << "IP:" << c.ip << ", PORT:" << c.port << ", STATUS:" << c.status << ", THREAD_NUM:" << c.thread_num << \
		", SOCKET_CONN_TIMEOUT:" << c.socket_conn_timeout << ", SOCKET_IDLE_TIMEOUT:" << c.socket_idle_timeout << \
		", SOCKET_SEND_TIMEOUT:" << c.socket_send_timeout << \
		", SOCKET_RECV_TIMEOUT:" << c.socket_recv_timeout << ", SOCKET_MAX_REQUEST_SIZE:" << c.socket_max_request_size << \
		", SOCKET_MAX_RESPONSE_SIZE:" << c.socket_max_response_size << ", CLIENT_CONN_POOL_SIZE:" << \
		c.client_conn_pool_size << ", LOG_CNF_FILE:" << c.log_cnf_file << ", ROOT_DATA_PATH:" << c.root_data_path << \
		", CREATE_TIME:" << c.create_time;
	return oss.str();
}

string mds_cnfs_2_string(list<MDS_CNF> l_mds) {
	ostringstream oss;
	oss << "[";
	for (list<MDS_CNF>::const_iterator iter = l_mds.begin(); l_mds.end() != iter; iter++) {
		oss << " IP:" << iter->ip << ", PORT:" << iter->port << ", STATUS:" << iter->status << ", WEIGHT:" << \
			iter->weight << ", ID:" << iter->id << ", THREAD_NUM:" << iter->thread_num << ", SOCKET_CONN_TIMEOUT:" << \
			iter->socket_conn_timeout << ", SOCKET_IDLE_TIMEOUT:" << \
			iter->socket_idle_timeout << ", SOCKET_SEND_TIMEOUT:" << iter->socket_send_timeout << \
			", SOCKET_RECV_TIMEOUT:" << iter->socket_recv_timeout << ", SOCKET_MAX_REQUEST_SIZE:" << \
			iter->socket_max_request_size << ", SOCKET_MAX_RESPONSE_SIZE:" << iter->socket_max_response_size << \
			", CLIENT_CONN_POOL_SIZE:" << iter->client_conn_pool_size << ", LOG_CNF_FILE:" << iter->log_cnf_file << \
			", ROOT_DATA_PATH:" << iter->root_data_path << ", CREATE_TIME:" << iter->create_time;
	}
	oss << "]";
	return oss.str();
}

string ds_cnfs_2_string(list<DS_CNF> l_ds) {
	ostringstream oss;
	oss << "[";
	for (list<DS_CNF>::const_iterator iter = l_ds.begin(); l_ds.end() != iter; iter++) {
		oss << " IP:" << iter->ip << ", PORT:" << iter->port << ", STATUS:" << iter->status << ", READ_WEIGHT:" << \
			iter->read_weight << ", WRITE_WEIGHT:" << iter->write_weight << ", ID:" << iter->id << ", MDS_ID:" << \
			iter->mds_id << ", THREAD_NUM:" << iter->thread_num << ", SOCKET_CONN_TIMEOUT:" << \
			iter->socket_conn_timeout << ", SOCKET_IDLE_TIMEOUT:" << \
			iter->socket_idle_timeout << ", SOCKET_SEND_TIMEOUT:" << iter->socket_send_timeout << \
			", SOCKET_RECV_TIMEOUT:" << iter->socket_recv_timeout << ", SOCKET_MAX_REQUEST_SIZE:" << \
			iter->socket_max_request_size << ", SOCKET_MAX_RESPONSE_SIZE:" << iter->socket_max_response_size << \
			", CLIENT_CONN_POOL_SIZE:" << iter->client_conn_pool_size << ", LOG_CNF_FILE:" << iter->log_cnf_file << \
			", ROOT_DATA_PATH:" << \
			iter->root_data_path << ", CREATE_TIME:" << iter->create_time;
	}
	oss << "]";
	return oss.str();
}

void * test_thread_routine(void * arg) {
	CnfSvrClient * c = (CnfSvrClient *)arg;
	while (true) {
		NS_CNF ns_cnf;
		list<MDS_CNF> l_mds;
		list<DS_CNF> l_ds;
		int ret = c->get_all_cnf(ns_cnf, l_mds, l_ds);
		if (ret < 0) {
//			cout << "get_all_cnf fail, ret:" << ret << endl;
//			return NULL;
		}
		
/*
		cout << "ns cnf:" << ns_cnf_2_string(ns_cnf) << ", mds cnfs:" << mds_cnfs_2_string(l_mds) << ", ds cnfs:" << \
			ds_cnfs_2_string(l_ds) << endl;
*/
		add_counter();
//		return NULL;
	}
	return NULL;
}


int test() {
	log4cxx::xml::DOMConfigurator::configure(g_log_conf_file.c_str());
	pthread_mutex_init(&g_mutex, NULL);
	g_time_start = time(NULL);
	CnfSvrClient c;
	c.init("127.0.0.1", 3501,  100,  15, 12, 13, -1);
	pthread_t t[THREAD_NUM];
	for (int i = 0; i < THREAD_NUM; i++) {
		pthread_create(&t[i], NULL, test_thread_routine, &c);
	}
	for (int i = 0; i < THREAD_NUM; i++) {
		pthread_join(t[i], NULL);
	}
	return 0;
}

int main(int argc, char * argv[]) {
	parse_args(argc, argv);
	test();
	return 0;
}
